#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "wallyingLib.h"


#define BLE_CONNECTION_CHANNEL_NUM (37)

uint32_t Connection_Access_Address = 0x43C6C5C7;
uint16_t Connection_Event_Counter = 522;//0;

uint16_t channelIdentifier = 0;

uint16_t connEventCounter = 0;
uint16_t paEventCounter = 0;
uint16_t bigEventCounter = 0;
uint16_t cisEventCounter = 0;


uint16_t prn_e = 0; /* pseudo-random numbers event */
uint16_t prn_s = 0; /* pseudo-random numbers subevent */


uint8_t hopIncrement = 6;//0;
uint8_t channelMap[5] =
//{0xFF, 0xFF, 0xFF, 0xFF, 0x1F};
{0x03, 0x00, 0xFE, 0x00, 0x10};

uint8_t unmappedChannel = 0;
uint8_t numUsedChannels = 0;

uint8_t remappingIndex = 0;
uint8_t remappingTable[BLE_CONNECTION_CHANNEL_NUM] = {0x00};


uint8_t dataChannelIndex = 0;


uint16_t XOR(uint16_t a, uint16_t b)
{
	return a ^ b;
}

uint16_t PERM(uint16_t a)
{
	uint8_t upper_8bits, lower_8bits;
	uint16_t output;
	upper_8bits = (a >> 8) & 0xFF;
	lower_8bits = (a >> 0) & 0xFF;
	bits_reverse(&upper_8bits, 8);
	bits_reverse(&lower_8bits, 8);
	output = (upper_8bits << 8) + lower_8bits;
	return output;
}

uint16_t MAM(uint16_t a, uint16_t b)
{
	return ((17 * a + b) & 0xFFFF);
}

void pseudo_random_number(uint16_t counter, uint16_t channelIdentifier)
{
	uint16_t temp = 0;
	temp = XOR(counter, channelIdentifier);
	temp = PERM(temp);
	temp = MAM(temp, channelIdentifier);
	temp = PERM(temp);
	temp = MAM(temp, channelIdentifier);
	temp = PERM(temp);
	temp = MAM(temp, channelIdentifier);
	prn_s =  temp;
	temp = XOR(temp, channelIdentifier);
	prn_e =  temp;
}


int main(int argc, char *argv[])
{
    printf("Hello World!\r\n");


    printf("Connection_Access_Address = 0x%08X\r\n", Connection_Access_Address);

	uint16_t upper_16bits;
	uint16_t lower_16bits;
    upper_16bits = (Connection_Access_Address >> 16) & 0xFFFF;
    lower_16bits = (Connection_Access_Address >> 0) & 0xFFFF;
	channelIdentifier = upper_16bits ^ lower_16bits;
	printf("channelIdentifier = 0x%04X\r\n", channelIdentifier);


	connEventCounter = Connection_Event_Counter;
	printf("connEventCounter = %d\r\n", connEventCounter);


	numUsedChannels = bits_count(channelMap, BLE_CONNECTION_CHANNEL_NUM);
	printf("numUsedChannels = %d\r\n", numUsedChannels);


	memset(remappingTable, 0, sizeof(remappingTable));
	for (int i = 0, j = 0; i < BLE_CONNECTION_CHANNEL_NUM; i++) {
		if (bit_get(channelMap, i)) {
			remappingTable[j] = i;
			j++;
		}
	}
//	for (int i = 0; i < numUsedChannels; i++) {
//		printf("%2d : %2d\r\n", i, remappingTable[i]);
//	}


	while (1)
	{
		pseudo_random_number(connEventCounter, channelIdentifier);

		unmappedChannel = prn_e % 37;

		if (bit_get(channelMap, unmappedChannel))
		{
			dataChannelIndex = unmappedChannel;
		}
		else
		{
			remappingIndex = (numUsedChannels * prn_e) / 65536;
			printf("remappingIndex = %d\r\n", remappingIndex);
			dataChannelIndex = remappingTable[remappingIndex];
		}

		printf("%d : dataChannelIndex = %d\r\n", connEventCounter, dataChannelIndex);

		connEventCounter++;

		system("pause");
	}


    system("pause");
    return 0;
}
